package org.origin.centre.model.vo;

import io.swagger.v3.oas.annotations.media.Schema;
import org.origin.centre.model.base.XPage;
import org.origin.centre.support.lang.util.Function2;
import org.origin.centre.support.utils.BasicUtil;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 分页通用响应-实体类
 *
 * @author ferret
 * @version 2024-05-08
 */
@SuppressWarnings("unused")
@Schema(description = "分页通用响应-实体类")
public class XPageVo<T> {
    @Schema(description = "当前页")
    private Integer pageNum;
    @Schema(description = "每页显示条数")
    private Integer pageSize;
    @Schema(description = "总数据量")
    private Long total;
    @Schema(description = "总数页数")
    private Integer pages;
    @Schema(description = "返回的数据")
    private List<T> list;

    public Integer getPageNum() {
        return this.pageNum;
    }

    public XPageVo<T> setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
        return this;
    }

    public Integer getPageSize() {
        return this.pageSize;
    }

    public XPageVo<T> setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
        return this;
    }

    public Long getTotal() {
        return total;
    }

    public XPageVo<T> setTotal(Long total) {
        this.total = total;
        return this;
    }

    public XPageVo<T> setTotalAndPages(Long total) {
        this.total = total;
        this.pages = BasicUtil.getPages(total, this.getPageSize());
        return this;
    }

    public Integer getPages() {
        return pages;
    }

    public XPageVo<T> setPages(Integer pages) {
        this.pages = pages;
        return this;
    }

    public List<T> getList() {
        return list;
    }

    public XPageVo<T> setList(List<T> list) {
        this.list = list;
        return this;
    }

    public XPageVo<T> of(Integer pageNum, Integer pageSize, Long total, List<T> list) {
        return new XPageVo<T>()
                .setPageNum(pageNum)
                .setPageSize(pageSize)
                .setTotalAndPages(total)
                .setList(list);
    }

    public <P> XPageVo<T> of(Integer pageNum, Integer pageSize, Long total, List<P> list, Function<P, T> function) {
        return this.of(pageNum, pageSize, total,
                list != null && list.size() > 0 ?
                        list.stream().map(function)
                                .collect(Collectors.toList()) : null);
    }

    public XPageVo<T> of(XPage<?> pageDto, Long total, List<T> list) {
        return this.of(pageDto.getPageNum(), pageDto.getPageSize(), total, list);
    }

    public <P> XPageVo<T> of(XPage<?> pageDto, Long total, List<P> list, Function<P, T> function) {
        return this.of(pageDto.getPageNum(), pageDto.getPageSize(), total, list, function);
    }

    public <P> XPageVo<T> of(XPage<?> pageDto, Long total, List<P> list, Class<T> clazz, Function2<P, Class<T>, T> function) {
        return this.of(pageDto.getPageNum(), pageDto.getPageSize(), total, list, e -> function.apply(clazz, e));
    }
}
